//
//  HHPMediatorManager.m
//  HHPLiveVideo
//
//  Created by 韩红坡 on 2016/12/30.
//  Copyright © 2016年 韩红坡. All rights reserved.
//

#import "HHPMediatorManager.h"

static NSString * const PREFIXTARGET   =   @"Target_";
static NSString * const PREFIXACTION   =    @"Action_";
static NSString * const CUSTOMSCHEME   =    @"HHPLiveVideo";

@implementation HHPMediatorManager

#pragma mark - public methods

+ (instancetype)sharedInstance
{
    static HHPMediatorManager *mediatorManager;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        mediatorManager = [[HHPMediatorManager alloc] init];
    });
    
    return mediatorManager;
}

- (id)externalCallModuleWithUrl:(NSURL *)url completion:(void (^)(NSDictionary *))completion
{
    if (![url.scheme isEqualToString:CUSTOMSCHEME])
    {
        // 不是特定的url 不跳转
        return @(NO);
    }
    
    NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
    NSString *urlString = [url query];
    for (NSString *param in [urlString componentsSeparatedByString:@"&"]) {
        NSArray *elts = [param componentsSeparatedByString:@"="];
        if([elts count] < 2) continue;
        
        [params setObject:[self urlDecodedString:[elts lastObject]] forKey:[elts firstObject]];
    }
    
    NSString *actionName = [url.path stringByReplacingOccurrencesOfString:@"/" withString:@""];
    
    //暂时针对URL的路由先简单处理，只是取对应的target名字和action名字，但这已经足以应对绝大部份需求。如果需要拓展，可以在这个方法调用之前加入完整的路由逻辑
    
    //取对应的target名字和action名字，然后通过本地调用执行target-action
    id result = [self nativeCallModuleWithTarget:url.host action:actionName params:params];
    if (completion) {
        if (result) {
            completion(@{@"result":result});
        } else {
            completion(nil);
        }
    }
    return result;
}

- (id)nativeCallModuleWithTarget:(NSString *)targetName action:(NSString *)actionName
{
    return [self nativeCallModuleWithTarget:targetName action:actionName params:nil];
}

- (id)nativeCallModuleWithTarget:(NSString *)targetName action:(NSString *)actionName params:(NSDictionary *)params
{
    NSString *targetClassString = [NSString stringWithFormat:@"%@%@",PREFIXTARGET, targetName];
    NSMutableString *actionString = [NSMutableString stringWithFormat:@"%@%@",PREFIXACTION, actionName];
    if (params) {
        [actionString appendString:@":"];
    }
    
    Class targetClass = NSClassFromString(targetClassString);
    id target = [[targetClass alloc] init];
    SEL action = NSSelectorFromString(actionString);
    
    if (target == nil) {
        // 这里是处理无响应请求的地方之一，这里是可以给一个固定的target专门处理这种情况。此处简单处理，如果没有可以响应的target，就直接return了。
        return nil;
    }
    
    if ([target respondsToSelector:action]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        if (params) {
            return [target performSelector:action withObject:params];
        } else {
            return [target performSelector:action];
        }
#pragma clang diagnostic pop
    } else {
        // 这里是处理无响应请求的地方，如果无响应，则尝试调用对应target的notFound方法统一处理
        SEL action = NSSelectorFromString(@"notFound:");
        if ([target respondsToSelector:action]) {
            if (!params) {
                params = @{};
            }
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
            return [target performSelector:action withObject:params];
#pragma clang diagnostic pop
        } else {
            // 这里也是处理无响应请求的地方，在notFound都没有的时候，可以用前面提到的固定的target来处理。此处暂时return了。
            return nil;
        }
    }
}

#pragma mark - private methods

- (NSString*)urlDecodedString:(NSString*)url
{
    NSString *result = (NSString *)CFBridgingRelease(CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault,(CFStringRef)url,CFSTR(""),kCFStringEncodingUTF8));
    return result;
    
}

@end
